﻿<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Floodlight OpenFlow Controller | Controller Status</title>
    <!-- Bootstrap Core CSS -->
    <link href="../bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- MetisMenu CSS -->
    <link href="../bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">
    <!-- Timeline CSS -->
    <link href="../dist/css/timeline.css" rel="stylesheet">
    <!-- Custom CSS -->
    <link href="../dist/css/sb-admin-2.css" rel="stylesheet">
    <!-- Morris Charts CSS -->
    <link href="../bower_components/morrisjs/morris.css" rel="stylesheet">
    <!-- Custom Fonts -->
    <link href="../bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

    <!-- Animate.css -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.4.0/animate.min.css" rel="stylesheet" type="text/css"/>
    <link href="../bower_components/pnotify/css/pnotify.css" rel="stylesheet"/>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div id="wrapper">
    <!-- Navigation -->
    <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
        <div class="navbar-header">

            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>

            <a class="navbar-brand" href="index.html" id="home-button-title">Floodlight OpenFlow Controller </a>

        </div>

        <!-- /.navbar-top-links -->
        <div class="navbar-default sidebar" role="navigation">
            <div class="sidebar-nav navbar-collapse">
                <nav id="navMenu"></nav>
            </div>
            <!-- /.sidebar-collapse -->
        </div>
        <!-- /.navbar-static-side -->

    </nav>
    <div id="page-wrapper">
        <div class="row">
            <div class="col-lg-12">
                <h3 class="page-header">Controller</h3>
            </div>
            <!-- /.col-lg-12 -->
        </div>

        <div class="row">

            <div class="col-lg-4 col-md-12">
                <div class="panel" id="controllerStatusPanel">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i id="controllerStatusIcon"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="controllerStatus">...</div>
                                <div>Controller Status</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="col-lg-4 col-md-12">
                <div class="panel-yellow">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i class="glyphicon glyphicon-time fa-5x"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="controllerUpTime">...</div>
                                <div>Uptime (HH-mm-ss)</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-lg-4 col-md-12">
                <div class="panel-primary">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i class="fa fa-user fa-5x"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="controllerRole">...</div>
                                <div>Controller Role <a href="#" class="btn btn-xs btn-success"
                                                        data-toggle="modal"
                                                        data-target=".bs-example-modal-sm">Change</a></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        </div>

        <!-- /.row -->
        <div class="row">
            <div class="col-lg-3 col-md-6">
                <div class="panel panel-red">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i class="fa fa-random fa-5x"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="switchCountDiv">0</div>
                                <div>Switches</div>
                            </div>
                        </div>
                    </div>
                    <a href="switches.html">
                        <div class="panel-footer">
                            <span class="pull-left">See All</span>
                            <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                            <div class="clearfix"></div>
                        </div>
                    </a>
                </div>
            </div>
            <div class="col-lg-3 col-md-6">
                <div class="panel panel-red">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i class="fa fa-laptop fa-5x"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="hostCountDiv">0</div>
                                <div>Hosts</div>
                            </div>
                        </div>
                    </div>
                    <a href="hosts.html">
                        <div class="panel-footer">
                            <span class="pull-left">See All</span>
                            <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                            <div class="clearfix"></div>
                        </div>
                    </a>
                </div>
            </div>
            <div class="col-lg-3 col-md-6">
                <div class="panel panel-red">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i class="fa fa-expand fa-5x"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="linkCountDiv">0</div>
                                <div>Connections (Links)</div>
                            </div>
                        </div>
                    </div>
                    <a href="links.html">
                        <div class="panel-footer">
                            <span class="pull-left">See All</span>
                            <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                            <div class="clearfix"></div>
                        </div>
                    </a>
                </div>
            </div>
            <div class="col-lg-3 col-md-6">
                <div class="panel panel-red">
                    <div class="panel-heading">
                        <div class="row">
                            <div class="col-xs-3">
                                <i class="fa fa-check-square-o fa-5x"></i>
                            </div>
                            <div class="col-xs-9 text-right">
                                <div class="huge" id="portCountDiv">0</div>
                                <div>Reserved Ports</div>
                            </div>
                        </div>
                    </div>
                    <a href="#">
                        <div class="panel-footer">
                            <span class="pull-left">See All</span>
                            <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                            <div class="clearfix"></div>
                        </div>
                    </a>
                </div>
            </div>
        </div>
        <!-- /.row -->

        <div class="row">
            <div class="col-lg-4 col-md-4">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <i class="fa fa-dashboard fa-fw"></i>JVM Memory Bloat
                    </div>
                    <!-- /.panel-heading -->
                    <div class="panel-body">

                        <div class="sidebar-widget">
                            <canvas width="150" height="80" id="foo" class=""
                                    style="width: 160px; height: 100px;"></canvas>
                            <div class="goal-wrapper">
                                <span class="gauge-value pull-left"></span>
                                <span id="gauge-text" class="gauge-value pull-left"></span>
                                <span id="goal-text" class="goal-value pull-right"></span>
                            </div>
                        </div>

                    </div>
                    <!-- /.panel-body -->
                </div>
            </div>

            <div class="col-lg-4">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <i class="fa fa-signal fa-fw"></i> Consumption Detail
                    </div>
                    <!-- /.panel-heading -->
                    <div class="panel-body">
                        <div class="list-group">
                            <a href="#" class="list-group-item">
                                <i class="fa fa-info fa-fw"></i> Total:
                                    <span class="pull-right text-muted small">
                                        <em>
                                            <div id="totalMemoryDiv"></div>
                                        </em>
                                    </span>
                            </a>
                            <a href="#" class="list-group-item">
                                <i class="fa fa-info fa-fw"></i> Used:
                                    <span class="pull-right text-muted small">
                                        <em>
                                            <div id="usedMemoryDiv"></div>
                                        </em>
                                    </span>
                            </a>
                            <a href="#" class="list-group-item">
                                <i class="fa fa-info fa-fw"></i> Free:
                                    <span class="pull-right text-muted small">
                                        <em>
                                            <div id="freeMemoryDiv"></div>
                                        </em>
                                    </span>
                            </a>

                        </div>
                        <!-- /.list-group -->
                    </div>
                    <!-- /.panel-body -->
                </div>
            </div>

            <div class="col-lg-4">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <i class="fa fa-table fa-fw"></i> Storage Tables
                    </div>
                    <!-- /.panel-heading -->
                    <div class="panel-body">
                        <div id="storageTables"></div>
                    </div>
                    <!-- /.panel-body -->
                </div>
            </div>

        </div>

        <div class="row">
            <div class="col-md-6 col-lg-6">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <i class="fa fa-table fa-fw"></i> Modules Loaded
                    </div>
                    <!-- /.panel-heading -->
                    <div class="panel-body">
                        <div id="loadedModules"></div>
                    </div>
                    <!-- /.panel-body -->
                </div>

            </div>

            <div class="col-md-6 col-lg-6">

                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <i class="fa fa-table fa-fw"></i> All Modules
                    </div>
                    <!-- /.panel-heading -->
                    <div class="panel-body">
                        <div id="allModules"></div>
                    </div>
                    <!-- /.panel-body -->
                </div>
            </div>
        </div>

        <!-- Small modal -->
        <div class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-hidden="true">
            <div class="modal-dialog modal-sm">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" id="roleModalCloseButton" data-dismiss="modal"
                                aria-label="Close">
                            <span aria-hidden="true">×</span>
                        </button>
                        <h4 class="modal-title" id="myModalLabel2">Change Role</h4>
                    </div>
                    <div class="modal-body">

                        <div class="form-group">
                            <div class="radio">
                                <label>
                                    <input type="radio" id="rbActive" name="iCheck"> ACTIVE
                                </label>
                            </div>
                            <div class="radio">
                                <label>
                                    <input type="radio" id="rbStandBy" name="iCheck"> STANDBY
                                </label>
                            </div>
                        </div>

                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-xs btn-default" data-dismiss="modal">Cancel</button>
                        <button type="button" id="btnChangeRole" class="btn btn-xs btn-primary">Change</button>
                    </div>
                </div>
            </div>
        </div>

        <div id="login-modal-include"></div>

    </div>
    <!-- /#page-wrapper -->
</div>
<!-- /#wrapper -->
<!-- jQuery -->
<script src="../bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="../bower_components/metisMenu/dist/metisMenu.min.js"></script>

<!-- Gauge Js -->
<script src="../bower_components/gauge/gauge.min.js"></script>
<script src="../bower_components/gauge/gauge_demo.js"></script>

<!-- Custom Theme JavaScript -->
<script src="../dist/js/sb-admin-2.js"></script>

<!-- PNotify -->
<script src="../bower_components/pnotify/pnotify.buttons.js"></script>
<script src="../bower_components/pnotify/pnotify.core.js"></script>
<script src="../bower_components/pnotify/pnotify.nonblock.js"></script>
<script src="../js/querystringparser.js"></script>
<script src="../js/jquery.cookie.js"></script>

<!-- Custom scripts to load in HTML -->
<script src="../js/navbar.js"></script>
<script>
    $(function(){
        $("#login-modal-include").load("loginmodal.html");
    });
</script>

<script type="text/javascript">
    /*
     * These cookies are set on the login page at login.html.
     * They are simply the IP address of your controller and the REST api port.
     * */
    var ipaddress = $.cookie('cip');
    if (ipaddress == null || ipaddress == "") window.location.href = "login.html";
    var restport = $.cookie('cport');
    if (restport == null || restport == "") window.location.href = "login.html";

    $('#login-modal button').on('click', function (e) {
        var $target = $(e.target);
        if ($target[0].id == "start-button") {
            $('#login-modal').on('hide.bs.modal', function (e) {
                if (!checkConnection($("#ipaddress").val(), $("#restport").val())) {
                    e.preventDefault();
                    e.stopImmediatePropagation();
                    return false;
                }
                else {
                    setIpAddress();
                    startRefresh();
                }
            });
        }
    });

    $(document).ready(function () {
        if (!checkConnection(ipaddress, restport)) {
            console.log('Trying to show modal');
            $('#login-modal').modal('show');
        }
        else startRefresh();
    });

    function getControllerRole() {
        $.ajax({
            url    : "http://" + ipaddress + ":" + restport + "/wm/core/role/json",
            success: function (data) {
                var role = data["role"];
                var changeTime = data["role-change-date-time"];

                if (role == "ACTIVE") {
                    $("#rbActive").prop("checked", true);

                }
                else if (role == "STANDBY") {
                    $("#rbStandBy").prop("checked", true);
                }

                $("#controllerRole").html(role);
            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * This function brings up a modal that allows you to change the controller role,
     * either to Active or Standby
     * */
    $("#btnChangeRole").click(function () {

        var roleStandBy = $('input[id=rbStandBy]:checked').val();
        var roleActive = $('input[id=rbActive]:checked').val();
        var newRole = "";
        if (roleActive == "on") newRole = "ACTIVE";
        if (roleStandBy == "on") newRole = "STANDBY";

        if (newRole == "ACTIVE" || newRole == "STANDBY") {
            $.ajax({

                type    : "POST",
                dataType: 'json',
                url     : " http://" + ipaddress + ":" + restport + "/wm/core/role/json",
                data    : '{"role":' + "\"" + newRole + "\"" + '}',
                success : function (data) {

                    if (data["TBD"] != "Not yet implemented") {
                        $("#roleModalCloseButton").click();

                        LoadControllerRole();

                    } else {

                        new PNotify({
                            title: 'Role Unchanged',
                            text : data["TBD"],
                            type : 'error',
                            hide : true
                        });

                    }

                },
                error   : function (jqXHR, textStatus, errorThrown) {
                }
            });
        }

    });

    /*
     * Gets the total uptime from the controller.
     * */
    function getControllerUptime() {
        $.ajax({
            url    : "http://" + ipaddress + ":" + restport + "/wm/core/system/uptime/json",
            success: function (data) {
                var uptime = data["systemUptimeMsec"];
                uptime = uptime / 1000;
                var hours = Math.floor(uptime / 3600);
                uptime %= 3600;
                var minutes = Math.floor(uptime / 60);
                var seconds = Math.floor(uptime % 60);
                $("#controllerUpTime").html(("0" + hours).slice(-2) + ":" + ("0" + minutes).slice(-2) + ":" +
                        ("0" + seconds).slice(-2));
            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * Gets the current status of the controller.
     * */
    function getControllerStatus() {
        $.ajax({
            url    : "http://" + ipaddress + ":" + restport + "/wm/core/health/json",
            success: function (data) {
                var healthy = data["healthy"];

                if (healthy == "1") {
                    $("#controllerStatus").html("Active");

                    $("#controllerStatusPanel").removeClass("panel-green");
                    $("#controllerStatusPanel").addClass("panel-green");
                    $("#controllerStatusIcon").addClass("glyphicon glyphicon-ok fa-5x");
                }
                else {
                    $("#controllerStatus").html("Passive");
                    $("#controllerStatusPanel").removeClass("panel-green");
                    $("#controllerStatusPanel").addClass("panel-red");
                    $("#controllerStatusIcon").removeClass("glyphicon glyphicon-ok fa-5x")
                    $("#controllerStatusIcon").addClass("glyphicon glyphicon-remove fa-5x");
                }

            },
            error  : function (jqXHR, textStatus, errorThrown) {
//                stopRefresh();
//                $('#login-modal').modal();
            }
        });
    }
    /*
     * Gets the current summary of switches, hosts, links, and ports connected to the controller.
     * This probably needs to be changed as it isn't accurate.
     * */
    function getControllerSummary() {
        $.ajax({
            url: "http://" + ipaddress + ":" + restport + "/wm/core/controller/summary/json",

            success: function (data) {

                var switchCount = data["# Switches"];
                var hostCount = data["# hosts"];
                var linkCount = data["# inter-switch links"];
                var portCount = data["# quarantine ports"];

                console.log(linkCount);

                $("#switchCountDiv").html(switchCount);
                $("#hostCountDiv").html(hostCount);
                $("#linkCountDiv").html(linkCount);
                $("#portCountDiv").html(portCount);
            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * Gets the current memory usage of the controller.
     * The gauge is created outside the function so it isn't
     * just created over and over again.
     * */

    function getControllerMemoryUsage() {
        $.ajax({
            url: "http://" + ipaddress + ":" + restport + "/wm/core/memory/json",

            success: function (data) {
                var total = data["total"];
                var free = data["free"];
                var used = Number(total) - Number(free);

                $("#goal-text").html(formatSizeUnits(total));
                $("#totalMemoryDiv").html(formatSizeUnits(total));
                $("#usedMemoryDiv").html(formatSizeUnits(used));
                $("#freeMemoryDiv").html(formatSizeUnits(free));

                gauge.maxValue = total; // set max gauge value
                gauge.animationSpeed = 32; // set animation speed (32 is default value)
                gauge.set(used); // set actual value
                gauge.setTextField(document.getElementById("gauge-text"));
            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * Loads storage tables.
     * */
    function getControllerStorageTables() {
        $.ajax({
            url    : " http://" + ipaddress + ":" + restport + "/wm/core/storage/tables/json",
            success: function (data) {

                var html = "<table class='table table-hover'>";

                for (var i = 0; i < data.length; i++) {

                    html += "<tr><td>" + data[i] + "</td></tr>";

                }
                html += "</table>";
                $("#storageTables").html(html);
            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * List the modules that are loaded in the controller.
     * */
    function getControllerLoadedModules() {
        $.ajax({
            url    : "http://" + ipaddress + ":" + restport + "/wm/core/module/loaded/json",
            success: function (data) {

                var obj = data;

                var html = "<table class='table table-hover'>";
                for (propName in obj) {

                    html += "<tr><td>" + propName.replace("net.floodlightcontroller.", "") + "</td></tr>";

                }
                html += "</table>";

                $("#loadedModules").html("");
                $("#loadedModules").html(html);

            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * List all of the modules in the controller.
     * */
    function getControllerModules() {
        $.ajax({
            url    : "http://" + ipaddress + ":" + restport + "/wm/core/module/all/json",
            success: function (data) {

                var obj = data;

                var html = "<table class='table table-hover'>";
                for (propName in obj) {

                    html += "<tr><td>" + propName.replace("net.floodlightcontroller.", "") + "</td></tr>";

                }
                html += "</table>";

                $("#allModules").html("");
                $("#allModules").html(html);

            },
            error  : function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    /*
     * Refreshes all of the values on the page every second.
     * */
    function startRefresh() {
        target = document.getElementById('foo'); // your canvas element
        gauge = new Gauge(target).setOptions(opts); // create sexy gauge!

        console.log("Refresh started!");
        refreshHandler = setInterval(getControllerValues, 1000);
        //getControllerValues();
    }

    function stopRefresh() {
        console.log("Refresh stopped!");
        clearInterval(refreshHandler);
    }


    /*
     * Used to get all of the controller values. Makes refreshing the page easier.
     **/
    function getControllerValues() {
        getControllerStatus();
        getControllerRole();
        getControllerSummary();
        getControllerMemoryUsage();
        getControllerUptime();
        getControllerStorageTables();
        getControllerLoadedModules();
        getControllerModules();
    }

    function checkConnection(ip, port) {
        var returnMessage = $.ajax({
            url    : "http://" + ip + ":" + port + "/wm/core/health/json",
            async: false,
            success: function (data) {
                console.log("Connection made!");
                return data;
            },
            error  : function (jqXHR, textStatus, errorThrown) {
                console.log("Connection cannot be made! :(");
            }
        });

        if (returnMessage.statusText == "OK") return true;
        else return false;
    }

    function setIpAddress() {

        var ip = $("#ipaddress").val();
        var port = $("#restport").val();

        $.cookie('cip', ip, { expires: 7 });
        $.cookie('cport', port, { expires: 7 });

        var readed = $.cookie('cip');

        if (readed != null && readed != "") {
            console.log("correct!");
            ipaddress = ip;
            restport = port;
        }
        else
        {
            console.log("Can not set the ip address!");
        }
    }

    /*
     * Helper function to convert bytes to a string with correct units.
     * */
    function formatSizeUnits(bytes) {
        if (bytes >= 1000000000) {
            bytes = (bytes / 1000000000).toFixed(2) + ' GB';
        }
        else if (bytes >= 1000000) {
            bytes = (bytes / 1000000).toFixed(2) + ' MB';
        }
        else if (bytes >= 1000) {
            bytes = (bytes / 1000).toFixed(2) + ' KB';
        }
        else if (bytes > 1) {
            bytes = bytes + ' bytes';
        }
        else if (bytes == 1) {
            bytes = bytes + ' byte';
        }
        else {
            bytes = '0 byte';
        }
        return bytes;
    }
</script>

</body>
</html>
